import os, sys, time
import threading, traceback

parent_path = os.path.abspath(os.path.join(__file__, *([".."] * 5)))
sys.path.insert(0, parent_path)

from core.utils.logger import logging


class BaseTask:
    """TaskPipeline cfg中的子任务处理类
    会将输入的4个处理类按照(预处理preprocess, 预测predictor, 测后处理process 后处理postprocess)组成一个执行序列exe_seq
    流程:
        __init__
        set(如果需要设置参数)
        standby
            init_check
            遍历执行exe_seq中process的start
        __call__
            执行主代码
        stop(如果需要外部控制停止)

    input:
        predictor: 预测器资源
        process:
    """
    
    """status状态机
    状态机包含三个值:
    0: close状态, 默认的状态
    1: ready状态, 初始化完成的状态
    2: running状态, 运行中
    """
    status = 0
    def __init__(
        self,
        predictor,
        process,
        preprocess,
        postprocess,
        detector_tags,
    ) -> None:

        self.detector_tags = set(detector_tags)
        self.exe_seq = []
        for process_ in [preprocess, predictor, process, postprocess]:
            if not process_ is None:
                self.exe_seq.append(process_)
        self.processor = process
        self.preprocessor = preprocess
        self.postprocessor = postprocess
        self.predictor = predictor

    def set(self, data):
        assert self.status == 0
        if not self.preprocessor is None:
            self.preprocessor.set(data)
        if not self.processor is None:
            self.processor.set(data)
        if not self.postprocessor is None:
            self.postprocessor.set(data)

    def close(
        self,
    ):
        try:
            for process_ in self.exe_seq:
                if not process_ is None:
                    process_.close()
        except Exception as e:
            raise e
        finally:
            self.status = 0

    def __call__(self, data):
        data["detector_tags"] = self.detector_tags
        raise ImportError()

    def standby(self):
        try:
            assert self.status ==0, "Task status is running"
            for process_ in self.exe_seq:
                if not process_ is None:
                    process_.start()
            self.status = 1
        except Exception as e:
            raise e

    def is_close(self):
        return self.status == 0
    def is_standby(self):
        return self.status == 1
    def is_running(self):
        return self.status == 2
